package com.wulis.provider.authority.service.impl;

import static com.wulis.common.model.enums.HttpStatusEnum.ROLE_MARK_EXISTS;

import java.util.List;
import java.util.Set;

import org.springframework.beans.BeanUtils;
import org.springframework.dao.DuplicateKeyException;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.wulis.common.exception.BusinessException;
import com.wulis.common.model.enums.DeletedStateEnum;
import com.wulis.common.support.BaseServiceImpl;
import com.wulis.provider.authority.annotation.RoleChange;
import com.wulis.provider.authority.mapper.RoleMapper;
import com.wulis.provider.authority.model.bo.RoleBo;
import com.wulis.provider.authority.model.dto.InsertRoleDto;
import com.wulis.provider.authority.model.dto.QueryRolePageDto;
import com.wulis.provider.authority.model.dto.UpdateRoleDto;
import com.wulis.provider.authority.model.entity.Role;
import com.wulis.provider.authority.model.vo.QueryRoleListVo;
import com.wulis.provider.authority.model.vo.QueryRolePageVo;
import com.wulis.provider.authority.model.vo.QueryRoleVo;
import com.wulis.provider.authority.service.RoleMenuService;
import com.wulis.provider.authority.service.RoleService;

import lombok.AllArgsConstructor;
import lombok.NonNull;
import lombok.extern.slf4j.Slf4j;

/**
 * 权限管理:角色表 Service实现类
 *
 * @author WuliBao
 * @date 2020-04-17
 */
@Slf4j
@Service
@AllArgsConstructor
public class RoleServiceImpl extends BaseServiceImpl<RoleMapper, Role> implements RoleService {
    
    private final RoleMapper roleMapper;
    
    private final RoleMenuService roleMenuService;
    
    /**
     * WEB:查询角色列表(分页)
     * 
     * @param queryRolePageDto queryRolePageDto
     * @return IPage
     */
    @Override
    public IPage<QueryRolePageVo> queryRolePage(@NonNull QueryRolePageDto queryRolePageDto) {
        Page<QueryRolePageVo> page = new Page<>(queryRolePageDto.getPageNumber(), queryRolePageDto.getPageSize());
        return roleMapper.queryRolePage(page,
            queryRolePageDto.getRoleName(),
            queryRolePageDto.getRoleMark(),
            queryRolePageDto.getEnable());
    }
    
    /**
     * WEB:查询角色列表(全量)
     * 
     * @param enable enable
     * @return role list
     */
    @Override
    public List<QueryRoleListVo> queryRoleList(Integer enable) {
        return roleMapper.queryRoleList(enable);
    }
    
    /**
     * WEB:查询角色及权限信息
     * 
     * @param roleId roleId
     * @return QueryRoleVo
     */
    @Override
    public QueryRoleVo queryRole(@NonNull Long roleId) {
        return roleMapper.queryRole(roleId);
    }
    
    /**
     * WEB:新增角色
     * 
     * @param insertRoleDto insertRoleDto
     * @return InsertRoleVo
     */
    @Override
    @RoleChange
    @Transactional(rollbackFor = Exception.class)
    public Integer insertRole(@NonNull InsertRoleDto insertRoleDto) {
        // 新增角色
        Role role = new Role();
        BeanUtils.copyProperties(insertRoleDto, role);
        int insert;
        try {
            insert = roleMapper.insert(role);
        }
        catch (DuplicateKeyException e) {
            throw new BusinessException(ROLE_MARK_EXISTS);
        }
        if (!insertRoleDto.getMenuIds().isEmpty()) {
            // 新增角色菜单关联关系
            roleMenuService.insertBatchRoleMenu(role.getId(), insertRoleDto.getMenuIds());
        }
        return insert;
    }
    
    /**
     * WEB:修改角色
     * 
     * @param updateRoleDto updateRoleDto
     * @return Integer
     */
    @Override
    @RoleChange
    @Transactional(rollbackFor = Exception.class)
    public Integer updateRole(@NonNull UpdateRoleDto updateRoleDto) {
        // 修改角色
        Role role = new Role();
        BeanUtils.copyProperties(updateRoleDto, role);
        int update;
        try {
            update = roleMapper.updateById(role);
        }
        catch (DuplicateKeyException e) {
            throw new BusinessException(ROLE_MARK_EXISTS);
        }
        if (updateRoleDto.getMenuIds() != null) {
            // 修改角色菜单关联关系
            roleMenuService.updateBatchRoleMenu(role.getId(), updateRoleDto.getMenuIds());
        }
        return update;
    }
    
    /**
     * WEB:删除角色
     * 
     * @param roleId roleId
     * @return Integer
     */
    @Override
    @RoleChange
    @Transactional(rollbackFor = Exception.class)
    public Integer deleteRole(@NonNull Long roleId) {
        // 删除角色
        Role role = new Role();
        role.setId(roleId);
        role.setDeleted(DeletedStateEnum.IS_DELETED.value());
        int delete = roleMapper.updateById(role);
        // 删除角色菜单关联关系
        roleMenuService.deleteRoleMenu(role.getId());
        return delete;
    }
    
    /**
     * WEB:查询全部角色及对应的按钮权限集合
     * 
     * @return Set
     */
    @Override
    public Set<RoleBo> queryAllRoleButton() {
        return roleMapper.queryAllRoleButton();
    }
}
